package service

import (
	"GopherFocus/app/dao"
	"GopherFocus/app/model"
	"GopherFocus/app/shared"
	"GopherFocus/app/system/index/internal/define"
	"context"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/gtime"
	"time"
)

var File = fileService{}

type fileService struct{}

func (s *fileService) Upload(ctx context.Context, input define.FileUploadInput) (output *define.FileUploadOutput, err error) {
	// 获取上传路径配置
	uploadPath := g.Cfg().GetString("upload.file")
	if uploadPath == "" {
		return nil, gerror.Newf("上传路径配置不存在")
	}
	// 获取上传的文件名
	// 如果不使用随机生成的文件名，则使用上传文件名
	if input.Name != "" {
		input.File.Filename = input.Name
	}
	// 同一个用户不能在一分钟内连续上传10次
	count, err := dao.File.Ctx(ctx).
		Where(dao.File.C.UserId, shared.Context.Get(ctx).User.Id).
		WhereGTE(dao.File.C.CreatedAt, gtime.Now().Add(-time.Minute)).Count()
	if err != nil {
		return nil, err
	}
	if count >= model.FileMaxUploadCountMinute {
		return nil, gerror.Newf("您上传太频繁，请稍候继续操作")
	}
	// 获取当前的日期，构造文件上传路径
	dateDirName := gtime.Now().Format("Ymd")
	// *ghttp.UploadFile.Save(p1, p2 ...bool) p1表示文件保存的路径，p2表示的是否使用随机生成的文件名
	// 如果RandomName为False，则使用*ghttp.UploadFile.FileName作为文件名
	// fileName是文件名，不是路径
	fileName, err := input.File.Save(gfile.Join(uploadPath, dateDirName), input.RandomName)
	if err != nil {
		return nil, err
	}
	// 保存到数据库
	data := model.File{
		Name:   fileName,
		Src:    gfile.Join(uploadPath, dateDirName, fileName),
		Url:    "/upload/" + dateDirName + "/" + fileName,
		UserId: shared.Context.Get(ctx).User.Id,
	}
	result, err := dao.File.Ctx(ctx).Data(data).OmitEmpty().Insert()
	if err != nil {
		return nil, err
	}
	// 获取最后插入数据的id
	id, _ := result.LastInsertId()
	return &define.FileUploadOutput{
		Id:   uint(id),
		Name: data.Src,
		Path: data.Src,
		Url:  data.Url,
	}, nil
}
